package com.fand.platform.configuration.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.val;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.fand.dto.PaginationDto;
import com.fand.platform.configuration.dao.VariableDao;
import com.fand.platform.configuration.dto.VariableDto;

/**
 * 变量服务
 * 
 * @author yaoHT
 * 
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class VariableDefaultService implements VariableService {
	private VariableDao variableDao;

	@Override
	@Transactional
	public int deleteVariableBy1(VariableDto deleteVariable) {
		return this.variableDao.deleteVariableBy1(deleteVariable, new String[] {});
	}

	@Override
	@Transactional
	public int deleteVariableByIds(VariableDto deleteVariable) {
		return this.variableDao.deleteVariableByIds(deleteVariable);
	}

	@Override
	public List<VariableDto> findVariableBy1(VariableDto findVariable) {
		return this.variableDao.selectVariableBy1ForMappedObjectList(VariableDto.class, findVariable,
				new String[] {}, new String[] {});
	}

	@Override
	public List<VariableDto> findVariableBy2(VariableDto findVariable) {
		return this.variableDao.selectVariableBy1ForMappedObjectList(VariableDto.class, findVariable,
				new String[] {}, new String[] {});
	}

	@Override
	public VariableDto getVariableBy1(VariableDto getVariable) {
		return this.variableDao.selectVariableBy1ForMappedObject(VariableDto.class, getVariable, new String[] {},
				new String[] {});
	}

	@Override
	public VariableDto getVariableById(VariableDto getVariable) {
		return this.variableDao.selectVariableByIdForMappedObject(VariableDto.class, getVariable);
	}

	@Override
	@Cacheable(value = VariableService.CACHE_NAME)
	public Map<String, String> getVariableByTypeCoForMap(String typeCo) {
		List<VariableDto> variableList = this.variableDao.selectVariableByTypeCoForMappedObjectList(
				VariableDto.class, typeCo);

		if (CollectionUtils.isEmpty(variableList)) {
			return null;
		}

		val variableMap = new HashMap<String, String>();

		for (VariableDto variable : variableList) {
			variableMap.put(variable.getCode(), variable.getValue());
		}

		return variableMap;
	}

	@Override
	public PaginationDto<Map<String, Object>> paginationVariableBy1ForMapList(VariableDto paginationVariable) {
		return this.variableDao.paginationVariableBy1ForMapList(paginationVariable);
	}

	@Override
	public PaginationDto<VariableDto> paginationVariableBy1ForVariableList(VariableDto paginationVariable) {
		return this.variableDao.paginationVariableBy1ForMappedObjectList(VariableDto.class, paginationVariable);
	}

	@Override
	public List<Integer> readListVariableBy1(VariableDto readVariable) {
		return this.variableDao.selectVariableBy1ForObjectList(Integer.class, readVariable, null, new String[] {});
	}

	@Override
	public List<Integer> readListVariableBy2(VariableDto readVariable) {
		return this.variableDao.selectVariableBy2ForObjectList(Integer.class, readVariable, null);
	}

	@Override
	public Integer readVariableBy2ForInteger(VariableDto readVariable) {
		return this.variableDao.selectVariableBy2ForObject(Integer.class, readVariable, null);
	}

	@Override
	public Integer readVariableByTypeIdEqCodeNqIdForInteger(VariableDto readVariable) {
		return this.variableDao.selectVariableByTypeIdEqCodeNqIdForInteger(readVariable);
	}

	@Override
	@CacheEvict(value = VariableService.CACHE_NAME, allEntries = true)
	public void reload() {
	}

	@Override
	@Transactional
	public VariableDto saveVariableBy2ForVariable(VariableDto saveVariable) {
		VariableDto oldVariable = this.variableDao.selectVariableBy1ForMappedObject(VariableDto.class, saveVariable,
				new String[] {}, new String[] {});

		if (oldVariable == null) {
			this.variableDao.insertVariableBy1(saveVariable, new String[] {});

			return saveVariable;
		}

		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveVariable, oldVariable);

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.variableDao.updateVariableBy1(saveVariable, updateProperties, new String[] {});
		}

		return saveVariable;
	}

	@Override
	@Transactional
	public VariableDto saveVariableByIdOrCodeForVariable(VariableDto saveVariable) {
		String[] whereEqProperties;

		if (StringUtils.isNotBlank(saveVariable.getId())) {
			whereEqProperties = new String[] { "id" };
		} else {
			whereEqProperties = new String[] { "code" };
		}

		VariableDto oldVariable = this.variableDao.selectVariableBy1ForMappedObject(VariableDto.class, saveVariable,
				null, whereEqProperties);

		if (oldVariable == null) {
			saveVariable.setId(UUID.randomUUID().toString());
			saveVariable.setBeginDaTi(new Date());
			saveVariable.setEndDaTi(new DateTime(9999, 12, 31, 0, 0, 0, 0).toDate());

			this.variableDao.insertVariableBy1(saveVariable);

			return saveVariable;
		}

		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveVariable, oldVariable, "typeId",
				"code", "name", "value", "remark", "orderNum");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.variableDao.updateVariableBy1(saveVariable, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveVariable, oldVariable, updateProperties);
		}

		return oldVariable;
	}

	@Override
	@Transactional
	public int setVariableBy1(VariableDto setVariable) {
		return this.variableDao.updateVariableBy1(setVariable, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	public int setVariableBy2(VariableDto setVariable) {
		return this.variableDao.updateVariableBy2(setVariable);
	}
}